﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using BussinesLayer.Clases;
using CustomControl;
using DTO.Clases;
using Utilities;

namespace Aplicacion.Compras.IngresarCompra
{
    public partial class FrmIngresarCompra : Form
    {
        #region Atributos de Logica de Negocio

        private BussinesEstado miBussinesEstado;

        /// <summary>
        /// Objeto de logica de negocio de Proveedor.
        /// </summary>
        private BussinesProveedor miBussinesProveedor;

        /// <summary>
        /// Objeto para cargar registros Proveedor.
        /// </summary>
        private DTO.Clases.Proveedor MiProveedor;

        /// <summary>
        /// Objeto para cargar los datos de la medida del producto consultado.
        /// </summary>
        private ValorUnidadMedida miMedida;

        /// <summary>
        /// Objeto de logica de negocio de Producto.
        /// </summary>
        private BussinesProducto miBussinesProducto;

        /// <summary>
        /// Objeto de logica de negocio de Usuario.
        /// </summary>
        private BussinesUsuario miBussinesUsuario;

        /// <summary>
        /// Objeto de logica de negocio de Factura Proveedor.
        /// </summary>
        private BussinesFacturaProveedor miBussinesFacturaProveedor;

        #endregion

        #region Propiedades

        /// <summary>
        /// Representa un objeto para la carga de datos de FacturaProveedor.
        /// </summary>
        private FacturaProveedor miFactura;

        /// <summary>
        /// Obtiene o establece el valor de la fecha en que se ingresa la factura.
        /// </summary>
        private DateTime FechaHoy;

        /// <summary>
        /// Representa el objeto de estructura las Formas de Pago.
        /// </summary>
        private FormaPago miFormaPago;

        /// <summary>
        /// Colección que almacena objetos, en este caso Productos.
        /// </summary>
        private ArrayList ArrayProducto;

        /// <summary>
        /// Objeto para cargar Producto.
        /// </summary>
        private DTO.Clases.Producto MiProducto;

        /// <summary>
        /// Objeto para la carga del talla y color del producto.
        /// </summary>
        private TallaYcolor miTallaYcolor;

        /// <summary>
        /// Obtiene o establece el valor del Consecutivo del número de Lote.
        /// </summary>
        private int LoteConsecutivo;

        /// <summary>
        /// Obtiene o establece el valor del Lote.
        /// </summary>
        private string Lote;

        /// <summary>
        /// Representa una tabla de datos en memoria.
        /// </summary>
        private DataTable miTabla;

        #endregion

        #region Atributos de Validacion

        /// <summary>
        /// Obtiene o establece el valor que indica si se habilita color o no en el formulario segun la configuración.
        /// </summary>
        private bool EnableColor;

        /// <summary>
        /// Objeto que muestra mensajes de error.
        /// </summary>
        public ErrorProvider MiError;

        /// <summary>
        /// Obtiene o establece el valor que indica si se encuentra abierto el Form de Proveedor.
        /// </summary>
        private bool FormProveedor { set; get; }

        /// <summary>
        /// Obtiene o establece el valor que indica si se encuentra abierto el Form de Producto.
        /// </summary>
        private bool FormProducto = false;

        /// <summary>
        /// Indica si solo se realiza una transferencia de datos de Proveedor para ingreso de factura.
        /// </summary>
        private bool AddProveedor = false;

        /// <summary>
        /// Indica si solo se realiza una transferencia de datos de Medida y Color para ingreso de factura.
        /// </summary>
        private bool AddColor = false;

        /// <summary>
        /// Lista que acomula el valor del Id del Regimen de cada Proveedor que se carga.
        /// </summary>
        private List<int> IdRegimen;

        /// <summary>
        /// Indica que el Número de la Factura se ingreso correctamente.
        /// </summary>
        private bool NumFacturaMatch = false;

        /// <summary>
        /// Indica que la fecha concuerda con lo requerido.
        /// </summary>
        private bool FechaMatch = true;

        /// <summary>
        /// Indica que el descuento aplicado concuerda con lo requerido.
        /// </summary>
        private bool DescuentoMatch = true;

        /// <summary>
        /// Establece la regla de validacion que indica si se uso el metodo KeyPress del codigo.
        /// </summary>
        private bool KeyProductoPress = false;

        /// <summary>
        /// Indica que se ha cargado la Talla y el Color desde el Boton Agregar Registro.
        /// </summary>
        private bool LoadColorSize = false;

        /// <summary>
        /// Establece la regla de validacion que indica si se uso el metodo KeyPress del Codigo de Proveedor.
        /// </summary>
        private bool KeyProveedorPress = false;

        /// <summary>
        /// Establece la regla de validacion que indica si el campo Cantidad es valido.
        /// </summary>
        private bool CantidadMatch = true;

        /// <summary>
        /// Establece la regla de validacion que indica si el campo Valor es valido.
        /// </summary>
        private bool ValorMatch = true;

        /// <summary>
        /// Establece la regla de validación que indica si el campo Lote es válido.
        /// </summary>
        private bool LoteMatch = true;

        /// <summary>
        /// Establece la condición que indica si se aplica descuento por producto.
        /// </summary>
        private bool DesctoProducto = true;

        /// <summary>
        /// Establece la regla de validación que indica si el campo Descuento por Producto es válido.
        /// </summary>
        private bool DesctoProductoMatch = true;

        /// <summary>
        /// Indica si se quiere ver las medidas en el Grid.
        /// </summary>
        private bool BtnVerMedidaPress = true;

        /// <summary>
        /// Indica que no se quiere ver las medidas en el Grid.
        /// </summary>
        private bool BtnNoVerMedidaPress = true;

        /// <summary>
        /// Indica que se quiere ver el Color en el Grid.
        /// </summary>
        private bool BtnVerColorPress = true;

        /// <summary>
        /// Indica que no se quiere ver el Color en el Grid.
        /// </summary>
        private bool BtnNoVerColorPress = true;

        /// <summary>
        /// Indica que se quiere ver el Lote en el Grid.
        /// </summary>
        private bool BtnVerLotePress = true;

        /// <summary>
        /// Indica que no se quiere ver el Lote en el Grid.
        /// </summary>
        private bool BtnNoVerLotePress = true;

        /// <summary>
        /// Representa el texto: El campo Codigo del Proveedor es requerido.
        /// </summary>
        public string CodigoProveedorReq = "El campo Codigo del Proveedor es requerido.";

        /// <summary>
        /// Representa el texto: El Codigo del Proveedor que ingreso tiene formato incorrecto.
        /// </summary>
        public string CodigoProveedorFormato = "El Codigo del Proveedor que ingreso tiene formato incorrecto.";

        /// <summary>
        /// Representa el texto: El Codigo del Proveedor que ingreso no tiene registros en la base de datos.
        /// </summary>
        public string CodigoProveedorExiste = "El Codigo del Proveedor que ingreso no tiene registros en la base de datos.";

        /// <summary>
        /// Representa el mensaje: El campo Número de Factura es requerido.
        /// </summary>
        public string FacturaReq = "El campo Número de Factura es requerido.";

        /// <summary>
        /// El Número de Factura que ingreso tiene formato incorrecto.
        /// </summary>
        public string FacturaFormato = "El Número de Factura que ingreso tiene formato incorrecto.";

        /// <summary>
        /// Representa el mensaje: La Fecha limite debe ser superior a la de ingreso.
        /// </summary>
        public string ErrorFecha = "La Fecha limite debe ser superior a la de ingreso.";

        /// <summary>
        /// Representa el texto: Debe ingresar el codigo del Proveedor para continuar con el proceso
        /// </summary>
        private const string ProveedorRequerido = "Debe ingresar el codigo del Proveedor para continuar con el proceso.";

        /// <summary>
        /// Representa el texto: El campo Codigo del Articulo es requerido.
        /// </summary>
        private const string CodigoProductoReq = "El campo Codigo del Articulo es requerido.";

        /// <summary>
        /// Representa el texto: El Codigo del Articulo que ingreso tiene formato incorrecto.
        /// </summary>
        private const string CodigoProductoFormato = "El Codigo del Articulo que ingreso tiene formato incorrecto.";

        /// <summary>
        /// Representa el texto: El Codigo del Articulo que ingreso no tiene registros en la base de datos.
        /// </summary>
        private const string CodigoProductoExiste = "El Codigo del Articulo que ingreso no tiene registros en la base de datos.";

        /// <summary>
        /// Representa el texto: El campo Cantidad es requerido.
        /// </summary>
        private const string CantidadReq = "El campo Cantidad es requerido.";

        /// <summary>
        /// Representa el texto: El campo Cantidad tiene formato incorrecto.
        /// </summary>
        private const string CantidadFormato = "El campo Cantidad tiene formato incorrecto.";

        /// <summary>
        /// Representa el texto: El campo Valor Unitario es requerido.
        /// </summary>
        private const string ValorReq = "El campo Valor Unitario es requerido.";

        /// <summary>
        /// Representa el texto: El campo Valor Unitario tiene formato incorrecto. 
        /// </summary>
        private const string ValorFormato = "El campo Valor Unitario tiene formato incorrecto. ";

        /// <summary>
        /// Representa El mensaje. El Número de lote que ingreso tiene formato incorrecto.
        /// </summary>
        private const string LoteFormat = "El Número de lote que ingreso tiene formato incorrecto.";

        #endregion

        #region Utilidades

        /// <summary>
        /// Objeto para hacer uso del Formulario lista de productos.
        /// </summary>
        Inventario.Agrupacion.frmListarProducto listaProducto;

        /// <summary>
        /// Objeto para hacer uso del Formulario de Proveedor.
        /// </summary>
        private Proveedor.frmProveedor formProveedor;

        /// <summary>
        /// Objeto para hacer uso del Formulario de Producto.
        /// </summary>
        Inventario.Producto.FrmIngresarProducto FrmProducto;

        /// <summary>
        /// Representa una pequeña ventana emergente que muestra una breve explicacion de la funcion del control.
        /// </summary>
        private ToolTip miToolTip;

        /// <summary>
        /// Objeto para el acceso al ensamblado de la aplicación.
        /// </summary>
        private System.Reflection.Assembly assembly;

        /// <summary>
        /// Representa el Stream de la Imagen de Medida.
        /// </summary>
        private System.IO.Stream ImgMedidaStream;

        /// <summary>
        /// Representa el Stream de la Imagen de Color.
        /// </summary>
        private System.IO.Stream ImgColorStream;

        /// <summary>
        /// Representa el Stream de la Imagen de Lote.
        /// </summary>
        private System.IO.Stream ImgLoteStream;

        /// <summary>
        /// Representa la ruta del ensamblado de la imagen de color gris de Medida.
        /// </summary>
        private const string ImagenMedida = "Aplicacion.Recursos.Iconos.medidaGris.png";

        /// <summary>
        /// Representa la ruta del ensamblado de la imagen de color gris de Color.
        /// </summary>
        private const string ImagenColor = "Aplicacion.Recursos.Iconos.colorGris.png";

        /// <summary>
        /// Representa la ruta del ensamblado de la imagen de color gris de Lote.
        /// </summary>
        private const string ImagenLote = "Aplicacion.Recursos.Iconos.loteGris.png";

        /// <summary>
        /// Objeto tipo hilo que me premite realiza ejecuciones asincronas y sincrona.
        /// </summary>
        private Thread miThread;

        /// <summary>
        /// Objeto que estructura los datos de un metodo de clase.
        /// </summary>
        private delegate void myDelegate();

        /// <summary>
        /// Objeto que representa el panel de opcion a mostrar.
        /// </summary>
        private OptionPane miOption;

        /// <summary>
        /// Obtiene o establece el valor que indica si el cambio se realizo con exito.
        /// </summary>
        private bool SuccessCambio = false;

        /// <summary>
        /// Obtiene o establece el valor que indica si el guardado se realizo con exito.
        /// </summary>
        private bool SuccessGuardado = false;

        /// <summary>
        /// Representa un objeto para el tratamiento de codigo dinamico del Panel Tributario
        /// </summary>
        private List<PanelTributario> miPanelTributario;

        /// <summary>
        /// Representa una variable para realizar conteo.
        /// </summary>
        private int Contador;

        /// <summary>
        /// Objeto que encapsula el origen de datos del DataGrid de Productos.
        /// </summary>
        private BindingSource miBindingSource;

        #endregion

        public FrmIngresarCompra()
        {
            InitializeComponent();
            miFactura = new FacturaProveedor();
            EnableColor = Convert.ToBoolean(AppConfiguracion.ValorSeccion("color"));
            FechaHoy = DateTime.Today;
            dtpFechaLimite.Value = FechaHoy;
            CargarUsuario();
            IdRegimen = new List<int>();
            miFormaPago = new FormaPago();
            miToolTip = new ToolTip();
            MiError = new ErrorProvider();
            miBussinesEstado = new BussinesEstado();
            miBussinesProveedor = new BussinesProveedor();
            miBussinesProducto = new BussinesProducto();
            miBussinesUsuario = new BussinesUsuario();
            miBussinesFacturaProveedor = new BussinesFacturaProveedor();
            miTabla = new DataTable();
            CrearDataTable();
            miTallaYcolor = new TallaYcolor();
            miBindingSource = new BindingSource();
            miPanelTributario = new List<PanelTributario>();
        }

        private void FrmIngresarCompra_Load(object sender, EventArgs e)
        {
            lblFechaIngreso.Text = FechaHoy.Day + " de " + UseDate.MesCorto(FechaHoy.Month) + " de " + FechaHoy.Year;
            //cbFormaPago.DataSource = miFormaPago.lista;
            miToolTip.SetToolTip(btnTallaYcolor, "Seleccionar Talla y Color");
            miToolTip.SetToolTip(rbtnDesctoProducto, "Aplicar descuento por Producto.");
            miToolTip.SetToolTip(pbProducto, "Aplicar descuento por Producto.");
            miToolTip.SetToolTip(rbtnDesctoFactura, "Aplicar descuento por Factura.");
            miToolTip.SetToolTip(pbFactura, "Aplicar descuento por Factura.");
            CompletaEventos.Completa += new CompletaEventos.CompletaAccion(CompletaEventos_Completo);
            CompletaEventos.Completam += new CompletaEventos.CompletaAccionm(CompletaEventosm_Completo);
            CompletaEventos.CompletaEditProveedor +=
                new CompletaEventos.CompletaAccionEditProveedor(CompletaEventos_Completo);
            assembly = System.Reflection.Assembly.GetExecutingAssembly();
            CargarRecursos();
            dgvListaArticulos.AutoGenerateColumns = false;
            dgvListaArticulos.DataSource = miBindingSource;
        }

        private void FrmIngresarCompra_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.F12)
            {
                lkbGenerarLote_LinkClicked(null, null);
            }
        }

        private void FrmIngresarCompra_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (dgvListaArticulos.RowCount != 0)
            {
                DialogResult rta = MessageBox.Show("Esta apunto de salir.\n¿Desea guardar los cambios?",
                    "Factura Proveedor", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
                if (rta.Equals(DialogResult.Yes))
                {
                    tsGuardar_Click(tsGuardar, new EventArgs());
                    CerrarForms();
                }
                else
                {
                    if (rta.Equals(DialogResult.Cancel))
                    {
                        e.Cancel = true;
                    }
                    else
                    {
                        CerrarForms();
                    }
                }
            }
            else
            {
                CerrarForms();
            }
        }

        private void tsGuardar_Click(object sender, EventArgs e)
        {
            var codigoProveedor = ValidarCodigoProveedor();
            txtNumeroFactura_Validating(null, null);
            dtpFechaLimite_Validating(null, null);
            txtDescuento_KeyPress(null, new KeyPressEventArgs((char)Keys.Enter));
            if (MiProveedor != null)
            {
                if (miTabla.Rows.Count != 0)
                {
                    if (codigoProveedor && NumFacturaMatch && FechaMatch && DescuentoMatch)
                    {
                        DialogResult rta = MessageBox.Show("¿Está seguro(a) de guardar la Factura?", "Factura Proveedor",
                            MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                        if (rta.Equals(DialogResult.Yes))
                        {
                            CargarFactura();
                            KeyProductoPress = true;
                            miOption = new OptionPane();
                            miOption.FrmProgressBar.barraProgreso.Style = ProgressBarStyle.Marquee;
                            miOption.FrmProgressBar.Closed_ = true;
                            miOption.ProgressShow("Espere mientras se realizan las operaciones necesarias...",
                                "Operación en progreso");
                            this.Enabled = false;
                            miThread = new Thread(IniciarGuardado);
                            miThread.Start();
                        }
                    }
                }
                else
                {
                    OptionPane.MessageError("Debe cargar los Producto a la Factura para guardarla.");
                }
            }
            else
            {
                OptionPane.MessageError("Debe selecionar un Proveedor para la Factura.");
            }
        }

        private void tsBtnConsulta_Click(object sender, EventArgs e)
        {
            if (!FormProveedor)
            {
                var formConsulta = new FrmConsulta();
                formConsulta.MdiParent = this.MdiParent;
                FormProveedor = true;
                formConsulta.Show();
            }
        }

        private void tsSalir_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void txtCodigoProveedor_KeyPress(object sender, KeyPressEventArgs e)
        {
            try
            {
                if (e.KeyChar == (char)Keys.Enter)
                {
                    if (ValidarCodigoProveedor())
                    {
                        var codigo = Convert.ToInt32(txtCodigoProveedor.Text);
                        if (miBussinesProveedor.ExisteProveedorConCodigo(codigo))
                        {
                            if (MiProveedor != null)
                            {
                                DialogResult rta = MessageBox.Show("¿Está seguro de querer cambiar el Proveedor de la Factura?",
                                    "Información", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                                if (rta == DialogResult.Yes)
                                {
                                    MiProveedor = miBussinesProveedor.ConsultarPrveedorBasico(codigo);
                                    KeyProveedorPress = true;
                                    txtNumeroFactura.Focus();
                                    miOption = new OptionPane();
                                    miOption.FrmProgressBar.barraProgreso.Style = ProgressBarStyle.Marquee;
                                    miOption.FrmProgressBar.Closed_ = true;
                                    miOption.ProgressShow("Espere mientras se realizan las operaciones necesarias...",
                                        "Operacion en progreso");
                                    this.Enabled = false;
                                    miThread = new Thread(new ThreadStart(IniciarCambio));
                                    miThread.Start();
                                }
                                else
                                {
                                    txtCodigoProveedor.Text = MiProveedor.CodigoInternoProveedor.ToString();
                                }
                            }
                            else
                            {
                                MiProveedor = miBussinesProveedor.ConsultarPrveedorBasico(codigo);
                                IdRegimen.Add(MiProveedor.IdRegimen);
                                txtNombreProveedor.Text = MiProveedor.CodigoInternoProveedor + " - NIT: " + MiProveedor.NitProveedor
                                    + " - " + MiProveedor.RazonSocialProveedor;
                                MiError.SetError(txtCodigoProveedor, null);
                                KeyProveedorPress = true;
                                txtNumeroFactura.Focus();
                            }
                        }
                        else
                        {
                            OptionPane.MessageInformation(CodigoProveedorExiste);
                            MiError.SetError(txtCodigoProveedor, CodigoProveedorExiste);
                            txtCodigoProveedor.Focus();
                        }
                    }
                    else
                    {
                        //txtCodigoProveedor.Focus();
                    }
                }
                else
                {
                    KeyProveedorPress = false;
                }
            }
            catch (Exception ex)
            { OptionPane.MessageError(ex.Message); }
        }

        private void txtCodigoProveedor_Validating(object sender, CancelEventArgs e)
        {
            try
            {
                if (!KeyProveedorPress)
                {
                    if (ValidarCodigoProveedor())
                    {
                        var codigo = Convert.ToInt32(txtCodigoProveedor.Text);
                        if (miBussinesProveedor.ExisteProveedorConCodigo(codigo))
                        {
                            if (MiProveedor != null)
                            {
                                DialogResult rta = MessageBox.Show("¿Esta seguro que quiere cambiar el Proveedor de la Factura?",
                                    "Información", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                                if (rta == DialogResult.Yes)
                                {
                                    MiProveedor = miBussinesProveedor.ConsultarPrveedorBasico(codigo);
                                    KeyProveedorPress = true;
                                    txtNumeroFactura.Focus();
                                    miOption = new OptionPane();
                                    miOption.FrmProgressBar.barraProgreso.Style = ProgressBarStyle.Marquee;
                                    miOption.FrmProgressBar.Closed_ = true;
                                    miOption.ProgressShow("Espere mientras se realizan las operaciones necesarias...",
                                        "Operacion en progreso");
                                    this.Enabled = false;
                                    miThread = new Thread(new ThreadStart(IniciarCambio));
                                    miThread.Start();
                                }
                                else
                                {
                                    txtCodigoProveedor.Text = MiProveedor.CodigoInternoProveedor.ToString();
                                }
                            }
                            else
                            {
                                MiProveedor = miBussinesProveedor.ConsultarPrveedorBasico(codigo);
                                IdRegimen.Add(MiProveedor.IdRegimen);
                                txtNombreProveedor.Text = MiProveedor.CodigoInternoProveedor + " - NIT: " + MiProveedor.NitProveedor
                                        + " - " + MiProveedor.RazonSocialProveedor;
                                MiError.SetError(txtCodigoProveedor, null);
                                KeyProveedorPress = true;
                                txtNumeroFactura.Focus();
                            }
                        }
                        else
                        {
                            OptionPane.MessageInformation(CodigoProveedorExiste);
                            MiError.SetError(txtCodigoProveedor, CodigoProveedorExiste);
                            txtCodigoProveedor.Focus();
                        }
                    }
                    else
                    {
                        //txtCodigoProveedor.Focus();
                    }
                }
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }
        }

        private void btnBuscarProveedor_Click(object sender, EventArgs e)
        {
            if (!FormProveedor)
            {
                formProveedor = new Proveedor.frmProveedor();
                formProveedor.Extension = true;
                formProveedor.tcProveedor.SelectTab(1);
                FormProveedor = true;
                formProveedor.MdiParent = this.MdiParent;
                formProveedor.Show();
                AddProveedor = true;
            }
        }

        private void txtNumeroFactura_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                cbFormaPago.Focus();
            }
        }

        private void txtNumeroFactura_Validating(object sender, CancelEventArgs e)
        {
            if (!Validacion.EsVacio(txtNumeroFactura, MiError, FacturaReq))
            {
                if (Validacion.ConFormato(Validacion.TipoValidacion.NumeroGuion,
                    txtNumeroFactura, MiError, FacturaFormato))
                {
                    NumFacturaMatch = true;
                }
                else
                    NumFacturaMatch = false;
            }
            else
                NumFacturaMatch = false;
        }

        private void cbFormaPago_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                dtpFechaLimite.Focus();
            }
        }

        private void cbFormaPago_SelectionChangeCommitted(object sender, EventArgs e)
        {
            dtpFechaLimite.Value = FechaHoy;
        }

        private void dtpFechaLimite_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                txtCodigoArticulo.Focus();
            }
        }

        private void dtpFechaLimite_Validating(object sender, CancelEventArgs e)
        {
            var id = (int)cbFormaPago.SelectedValue;
            if (id == 2)
            {
                if (dtpFechaLimite.Value <= FechaHoy)
                {
                    MiError.SetError(dtpFechaLimite, ErrorFecha);
                    FechaMatch = false;
                }
                else
                {
                    MiError.SetError(dtpFechaLimite, null);
                    FechaMatch = true;
                }
            }
            else
            {
                FechaMatch = true;
            }
        }

        private void rbtnDesctoProducto_Click(object sender, EventArgs e)
        {
            if (dgvListaArticulos.RowCount != 0 && !DesctoProducto)
            {
                DialogResult rta = MessageBox.Show("¿Está seguro que quiere aplicar Descuento por Producto?",
                    "Factura Proveedor", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (rta.Equals(DialogResult.Yes))
                {
                    txtDescuentoFactura.Enabled = false;
                    txtDescuentoProducto.Enabled = true;
                    DesctoProducto = true;
                    txtDescuento.Text = "0";
                    txtDescuentoProducto.Text = "0";
                    txtDescuentoFactura.Text = "0";
                    CambiarDescuento();
                    OptionPane.MessageInformation("Debe editar el descuento de cada registro de Producto de la Factura.");
                }
                else
                {
                    rbtnDesctoFactura.Checked = true;
                    txtDescuentoFactura.Enabled = true;
                    txtDescuentoProducto.Enabled = false;
                }
            }
            else
            {
                DesctoProducto = true;
                txtDescuentoFactura.Enabled = false;
                txtDescuentoProducto.Enabled = true;
                txtDescuento.Text = "0";
                txtDescuentoProducto.Text = "0";
                txtDescuentoFactura.Text = "0";
            }
        }

        private void rbtnDesctoFactura_Click(object sender, EventArgs e)
        {
            if (dgvListaArticulos.RowCount != 0 && DesctoProducto)
            {
                DialogResult rta = MessageBox.Show("¿Está seguro que quiere aplicar Descuento por Factura?",
                    "Factura Proveedor", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                if (rta.Equals(DialogResult.Yes))
                {
                    txtDescuentoFactura.Enabled = true;
                    txtDescuentoProducto.Enabled = false;
                    DesctoProducto = false;
                    txtDescuentoFactura.Focus();
                }
                else
                {
                    rbtnDesctoProducto.Checked = true;
                    txtDescuentoFactura.Enabled = false;
                    txtDescuentoProducto.Enabled = true;
                }
            }
            else
            {
                DesctoProducto = false;
                txtDescuentoFactura.Enabled = true;
                txtDescuentoProducto.Enabled = false;
                txtDescuento.Text = "0";
                txtDescuentoProducto.Text = "0";
            }
        }

        private void txtDescuentoFactura_Click(object sender, EventArgs e)
        {
            txtDescuentoFactura.SelectAll();
        }

        private void txtDescuentoFactura_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                if (!String.IsNullOrEmpty(txtDescuentoFactura.Text))
                {
                    if (Validacion.ConFormato(Validacion.TipoValidacion.NumerosYPunto, txtDescuentoFactura,
                        MiError, "El valor del Descuento que ingreso tiene formato incorrecto."))
                    {
                        if (Convert.ToDouble(txtDescuentoFactura.Text.Replace('.', ',')) > 100)
                        {
                            MiError.SetError(txtDescuentoFactura, "El porcentaje de descuento no puede ser superior al 100%.");
                            DescuentoMatch = false;
                        }
                        else
                        {
                            MiError.SetError(txtDescuentoFactura, null);
                            DescuentoMatch = true;
                            if (dgvListaArticulos.RowCount != 0)
                            {
                                CambiarDescuento();
                            }
                        }
                    }
                }
                else
                {
                    txtDescuentoFactura.Text = "0";
                    DescuentoMatch = true;
                }
            }
        }

        private void txtDescuentoFactura_Validating(object sender, CancelEventArgs e)
        {
            txtDescuentoFactura_KeyPress(null, new KeyPressEventArgs((char)Keys.Enter));
        }

        private void txtCodigoArticulo_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                if (MiProveedor != null)
                {
                    if (ValidarCodigo() || ValidarCodigoBarras())
                    {
                        if (ExisteProducto(txtCodigoArticulo.Text))
                        {
                            CargarProducto(txtCodigoArticulo.Text);
                            MiError.SetError(txtCodigoArticulo, null);
                            KeyProductoPress = true;
                            txtCantidad.Focus();
                        }
                        else
                        {
                            OptionPane.MessageInformation(CodigoProductoExiste);
                            MiError.SetError(txtCodigoArticulo, CodigoProductoExiste);
                            txtCodigoArticulo.Focus();
                        }
                    }
                    else
                    {
                        txtCodigoArticulo.Focus();
                    }
                }
                else
                {
                    OptionPane.MessageInformation(ProveedorRequerido);
                    KeyProductoPress = true;
                    txtCodigoProveedor.Focus();
                    txtCodigoArticulo.Text = "";
                }
            }
            else
            {
                KeyProductoPress = false;
            }
        }

        private void txtCodigoArticulo_Validating(object sender, CancelEventArgs e)
        {
            if (!KeyProductoPress)
            {
                if (MiProveedor != null)
                {
                    if (ValidarCodigo() || ValidarCodigoBarras())
                    {
                        if (ExisteProducto(txtCodigoArticulo.Text))
                        {
                            CargarProducto(txtCodigoArticulo.Text);
                            MiError.SetError(txtCodigoArticulo, null);
                            txtCantidad.Focus();
                        }
                        else
                        {
                            OptionPane.MessageError(CodigoProductoExiste);
                            MiError.SetError(txtCodigoArticulo, CodigoProductoExiste);
                            txtCodigoArticulo.Focus();
                        }
                    }
                    else
                    {
                        txtCodigoArticulo.Focus();
                    }
                }
                else
                {
                    OptionPane.MessageInformation(ProveedorRequerido);
                    txtCodigoProveedor.Focus();
                    txtCodigoArticulo.Text = "";
                }
            }
        }

        private void btnBuscarArticulo_Click(object sender, EventArgs e)
        {
            if (!FormProducto)
            {
                FrmProducto = new Inventario.Producto.FrmIngresarProducto();
                FrmProducto.MdiParent = this.MdiParent;
                FrmProducto.Extencion = true;
                FrmProducto.Edit = true;
                FormProducto = true;
                FrmProducto.tabControlProducto.SelectTab(1);
                FrmProducto.Show();
            }
        }

        private void txtCantidad_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                txtValorUnitario.Focus();
            }
        }

        private void txtCantidad_Validating(object sender, CancelEventArgs e)
        {
            if (!Validacion.EsVacio(txtCantidad, MiError, CantidadReq))
            {
                if (Validacion.ConFormato(Validacion.TipoValidacion.Numeros,
                    txtCantidad, MiError, CantidadFormato))
                {
                    CantidadMatch = true;
                }
                else
                    CantidadMatch = false;
            }
            else
                CantidadMatch = false;
        }

        private void txtValorUnitario_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                if (txtDescuentoProducto.Enabled)
                {
                    txtDescuentoProducto.Focus();
                }
                else
                {
                    txtLote.Focus();
                }
            }
        }

        private void txtValorUnitario_Validating(object sender, CancelEventArgs e)
        {
            if (!Validacion.EsVacio(txtValorUnitario, MiError, ValorFormato))
            {
                if (Validacion.ConFormato(Validacion.TipoValidacion.Numeros,
                    txtValorUnitario, MiError, ValorFormato))
                {
                    ValorMatch = true;
                }
                else
                    ValorMatch = true;
            }
            else
                ValorMatch = false;
        }

        private void txtDescuentoProducto_Click(object sender, EventArgs e)
        {
            txtDescuentoProducto.SelectAll();
        }

        private void txtDescuentoProducto_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                if (!String.IsNullOrEmpty(txtDescuentoProducto.Text))
                {
                    if (Validacion.ConFormato(Validacion.TipoValidacion.NumerosYPunto, txtDescuentoProducto,
                        MiError, "El valor del Descuento que ingreso tiene formato incorrecto."))
                    {
                        if (Convert.ToDouble(txtDescuentoProducto.Text) > 100)
                        {
                            MiError.SetError(txtDescuentoProducto, "El porcentaje de descuento no puede ser superior al 100%.");
                            DesctoProductoMatch = false;
                        }
                        else
                        {
                            MiError.SetError(txtDescuentoProducto, null);
                            DesctoProductoMatch = true;
                            txtLote.Focus();
                        }
                    }
                }
                else
                {
                    txtDescuentoProducto.Text = "0";
                    DesctoProductoMatch = true;
                    txtLote.Focus();
                }
            }
        }

        private void txtDescuentoProducto_Validating(object sender, CancelEventArgs e)
        {
            txtDescuentoProducto_KeyPress(null, new KeyPressEventArgs((char)Keys.Enter));
        }

        private void txtLote_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                if (btnTallaYcolor.Enabled)
                {
                    btnTallaYcolor.Focus();
                }
                else
                {
                    btnAgregar.Focus();
                }
            }
        }

        private void txtLote_Validating(object sender, CancelEventArgs e)
        {
            if (!String.IsNullOrEmpty(txtLote.Text))
            {
                if (Validacion.ConFormato(Validacion.TipoValidacion.LetrasGuionNumeros,
                    txtLote, MiError, LoteFormat))
                {
                    LoteMatch = true;
                }
                else
                    LoteMatch = false;
            }
            else
                LoteMatch = true;
        }

        private void lkbGenerarLote_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            txtLote.Text = LoteConsecutivo.ToString();
            txtLote_KeyPress(txtLote, new KeyPressEventArgs((char)Keys.Enter));
        }

        private void btnTallaYcolor_Click(object sender, EventArgs e)
        {
            if (!FormProveedor)
            {
                if (MiProducto != null)
                {
                    if (MiProducto.AplicaTalla || MiProducto.AplicaColor)
                    {
                        FormProveedor = true;
                        listaProducto = new Inventario.Agrupacion.frmListarProducto();
                        listaProducto.MdiParent = this.MdiParent;
                        listaProducto.CargarProducto(MiProducto.CodigoInternoProducto);
                        AddColor = true;
                        listaProducto.Show();
                    }
                }
                else
                {
                    OptionPane.MessageInformation("Debe selecciona un Articulo primero.");
                }
            }
        }

        private void btnAgregar_Click(object sender, EventArgs e)
        {
            txtCantidad_Validating(null, null);
            txtValorUnitario_Validating(null, null);
            txtLote_Validating(null, null);
            if (ArrayProducto != null && CantidadMatch && ValorMatch && LoteMatch && DesctoProductoMatch)
            {
                if (!String.IsNullOrEmpty(txtLote.Text))
                {
                    Lote = txtLote.Text;
                }
                else
                {
                    Lote = MiProducto.CodigoInternoProducto + "-" + CambiarSeparadorFecha(FechaHoy.ToShortDateString());
                }
                if ((MiProducto.AplicaTalla && miTallaYcolor.IdTalla == 0) ||
                   (MiProducto.AplicaColor && miTallaYcolor.IdColor == 0))
                {
                    LoadColorSize = true;
                    btnTallaYcolor_Click(this.btnTallaYcolor, null);
                    return;
                }
                else
                {
                    LoadColorSize = false;
                    EstructurarConsulta();
                }
            }
        }

        private void tsVerMedida_Click(object sender, EventArgs e)
        {
            if (BtnVerMedidaPress)
            {
                tsVerMedida.Image = new Bitmap(ImgMedidaStream);
                tsVerMedida.Text = "No Ver Unidad de Medida";
                BtnNoVerMedidaPress = true;
                BtnVerMedidaPress = false;
                dgvListaArticulos.Columns["Unidad"].Visible = true;
                dgvListaArticulos.Columns["Medida"].Visible = true;
                dgvListaArticulos.Columns["Articulo"].Width -= Unidad.Width;
                dgvListaArticulos.Columns["Articulo"].Width -= Medida.Width;
            }
            else
            {
                if (BtnNoVerMedidaPress)
                {
                    tsVerMedida.Image = ((Image)(miResources.GetObject("tsVerMedida.Image")));
                    tsVerMedida.Text = "Ver Unidad de Medida";
                    BtnNoVerMedidaPress = false;
                    BtnVerMedidaPress = true;
                    dgvListaArticulos.Columns["Unidad"].Visible = false;
                    dgvListaArticulos.Columns["Medida"].Visible = false;
                    dgvListaArticulos.Columns["Articulo"].Width += Unidad.Width;
                    dgvListaArticulos.Columns["Articulo"].Width += Medida.Width;
                }
            }
        }

        private void tsVerColor_Click(object sender, EventArgs e)
        {
            if (BtnVerColorPress)
            {
                tsVerColor.Image = new Bitmap(ImgColorStream);
                tsVerColor.Text = "No ver Color";
                BtnNoVerColorPress = true;
                BtnVerColorPress = false;
                dgvListaArticulos.Columns["Color"].Visible = true;
                dgvListaArticulos.Columns["Articulo"].Width -= Color.Width;
            }
            else
            {
                if (BtnNoVerColorPress)
                {
                    tsVerColor.Image = ((Image)(miResources.GetObject("tsVerColor.Image")));
                    tsVerColor.Text = "Ver Color";
                    BtnNoVerColorPress = false;
                    BtnVerColorPress = true;
                    dgvListaArticulos.Columns["Color"].Visible = false;
                    dgvListaArticulos.Columns["Articulo"].Width += Color.Width;
                }
            }
        }

        private void tsVerLote_Click(object sender, EventArgs e)
        {
            if (BtnVerLotePress)
            {
                tsVerLote.Image = new Bitmap(ImgLoteStream);
                tsVerLote.Text = "No Ver Lote";
                BtnNoVerLotePress = true;
                BtnVerLotePress = false;
                dgvListaArticulos.Columns["CLote"].Visible = true;
                dgvListaArticulos.Columns["Articulo"].Width -= CLote.Width;
            }
            else
            {
                if (BtnNoVerLotePress)
                {
                    tsVerLote.Image = ((Image)(miResources.GetObject("tsVerLote.Image")));
                    BtnNoVerLotePress = false;
                    BtnVerLotePress = true;
                    dgvListaArticulos.Columns["CLote"].Visible = false;
                    dgvListaArticulos.Columns["Articulo"].Width += CLote.Width;
                }
            }
        }

        private void tsEditar_Click(object sender, EventArgs e)
        {
            if (dgvListaArticulos.RowCount != 0)
            {
                DialogResult rta = MessageBox.Show("¿Esta seguro de editar el registro?", "Factura Proveedor",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                if (rta.Equals(DialogResult.Yes))
                {
                    int id = (int)dgvListaArticulos.CurrentRow.Cells["Id"].Value;
                    var row = (from registro in miTabla.AsEnumerable()
                               where registro.Field<int>("Id") == id
                               select registro);
                    DataRow edit = null;
                    foreach (DataRow r in row)
                    {
                        edit = r;
                    }
                    txtCodigoArticulo.Text = edit["Codigo"].ToString();
                    txtCodigoArticulo_KeyPress(null, new KeyPressEventArgs((char)Keys.Enter));
                    miTallaYcolor.IdTalla = (int)edit["IdMedida"];
                    miTallaYcolor.Talla = edit["Medida"].ToString();
                    miTallaYcolor.IdColor = (int)edit["IdColor"];
                    try
                    {
                        miTallaYcolor.Color = (Image)edit["Color"];
                    }
                    catch
                    {
                        miTallaYcolor.Color = null;
                    }
                    txtCantidad.Text = edit["Cantidad"].ToString();
                    txtValorUnitario.Text = edit["ValorUnitario"].ToString();
                    txtLote.Text = edit["Lote"].ToString();
                    if (rbtnDesctoProducto.Checked)
                    {
                        txtDescuentoProducto.Text =
                            UseObject.RemoveCharacter(edit["Descuento"].ToString(), '%').ToString();
                    }
                    if (MiProveedor.IdRegimen == 1)
                    {
                        var total_ = edit.Field<double>("ValorMenosDescto") *
                                     Convert.ToInt32(edit["Cantidad"]);
                        var iva_ = UseObject.RemoveCharacter(edit.Field<string>("Iva"), '%');
                        var panelSearch = (from data in miPanelTributario
                                           where data.Iva == iva_
                                           select data).ToList();
                        panelSearch[0].TxtGravado.Text = UseObject.InsertSeparatorMil(
                            (UseObject.RemoveSeparatorMil(panelSearch[0].TxtGravado.Text) - total_).ToString());
                        panelSearch[0].TxtTotalIva.Text = UseObject.InsertSeparatorMil(
                            (UseObject.RemoveSeparatorMil(panelSearch[0].TxtTotalIva.Text) -
                             (iva_ * total_ / 100)).ToString());

                        txtIva.Text = UseObject.InsertSeparatorMil(
                        (UseObject.RemoveSeparatorMil(txtIva.Text) - (iva_ * total_ / 100)).ToString());
                    }

                    txtSubTotal.Text = UseObject.InsertSeparatorMil
                            (
                              (UseObject.RemoveSeparatorMil(txtSubTotal.Text) -
                              edit.Field<int>("ValorUnitario") * Convert.ToInt32(edit["Cantidad"]))
                              .ToString()
                            );

                    txtDescuento.Text = UseObject.InsertSeparatorMil
                        ((Convert.ToDecimal(txtDescuento.Text) -
                          ((Convert.ToDecimal(edit["ValorUnitario"]) - Convert.ToDecimal(edit["ValorMenosDescto"])) *
                            Convert.ToDecimal(edit["Cantidad"]))).ToString()
                        );

                    txtTotal.Text = UseObject.InsertSeparatorMil(
                        ((UseObject.RemoveSeparatorMil(txtSubTotal.Text) -
                         UseObject.RemoveSeparatorMil(txtDescuento.Text)) +
                         UseObject.RemoveSeparatorMil(txtIva.Text)).ToString());

                    miTabla.Rows.Remove(edit);
                    if (miTabla.Rows.Count != 0)
                    {
                        RecargarGridview();
                    }
                    else
                    {
                        dgvListaArticulos.Rows.RemoveAt(dgvListaArticulos.CurrentCell.RowIndex);
                    }
                }
            }
            else
            {
                OptionPane.MessageInformation("No hay registros para editar.");
            }
        }

        private void tsEliminar_Click(object sender, EventArgs e)
        {
            if (dgvListaArticulos.RowCount != 0)
            {
                string rta = OptionPane.OptionBox("Ingrese contraseña de Administrador.",
                    "Administrador", OptionPane.Icon.LoginAdmin);
                if (!rta.Equals("false"))
                {
                    if (miBussinesUsuario.VerificarUsuarioAdmin(Encode.Encrypt(rta)))
                    {
                        int id = (int)dgvListaArticulos.CurrentRow.Cells["Id"].Value;
                        var row = (from registro in miTabla.AsEnumerable()
                                   where registro.Field<int>("Id") == id
                                   select registro);
                        DataRow delet = null;
                        foreach (DataRow r in row)
                        {
                            delet = r;
                        }
                        var total_ = 0.0;
                        var iva_ = 0.0;
                        if (MiProveedor.IdRegimen == 1)
                        {
                            total_ = delet.Field<double>("ValorMenosDescto") *
                                     Convert.ToInt32(delet["Cantidad"]);
                            iva_ = UseObject.RemoveCharacter(delet.Field<string>("Iva"), '%');
                            var panelSearch = (from data in miPanelTributario
                                               where data.Iva == iva_
                                               select data).ToList();
                            panelSearch[0].TxtGravado.Text = UseObject.InsertSeparatorMil(
                                (UseObject.RemoveSeparatorMil(panelSearch[0].TxtGravado.Text) - total_).ToString());
                            panelSearch[0].TxtTotalIva.Text = UseObject.InsertSeparatorMil(
                                (UseObject.RemoveSeparatorMil(panelSearch[0].TxtTotalIva.Text) -
                                 (iva_ * total_ / 100)).ToString());
                            txtIva.Text = UseObject.InsertSeparatorMil(
                            (UseObject.RemoveSeparatorMil(txtIva.Text) - (iva_ * total_ / 100)).ToString());
                        }
                        txtSubTotal.Text = UseObject.InsertSeparatorMil
                            (
                              (UseObject.RemoveSeparatorMil(txtSubTotal.Text) -
                              delet.Field<int>("ValorUnitario") * Convert.ToInt32(delet["Cantidad"]))
                              .ToString()
                            );

                        txtDescuento.Text = UseObject.InsertSeparatorMil
                            (
                              (UseObject.RemoveSeparatorMil(txtDescuento.Text) -
                               ((delet.Field<int>("ValorUnitario") - delet.Field<double>("ValorMenosDescto")) *
                                 Convert.ToInt32(delet["Cantidad"]))).ToString()
                            );

                        txtTotal.Text = UseObject.InsertSeparatorMil(
                            ((UseObject.RemoveSeparatorMil(txtSubTotal.Text) -
                             UseObject.RemoveSeparatorMil(txtDescuento.Text)) +
                             UseObject.RemoveSeparatorMil(txtIva.Text)).ToString());
                        miTabla.Rows.Remove(delet);
                        if (miTabla.Rows.Count != 0)
                        {
                            RecargarGridview();
                        }
                        else
                        {
                            dgvListaArticulos.Rows.RemoveAt(dgvListaArticulos.CurrentCell.RowIndex);
                        }
                    }
                }
                else
                {
                    OptionPane.MessageError("La contraseña es incorrecta.");
                }
            }
            else
            {
                OptionPane.MessageInformation("No hay registros para eliminar.");
            }
        }

        private void txtDescuento_Click(object sender, EventArgs e)
        {
            txtDescuento.SelectAll();
        }

        private void txtDescuento_KeyPress(object sender, KeyPressEventArgs e)
        {
            /*if (e.KeyChar == (char)Keys.Enter)
            {
                if (!String.IsNullOrEmpty(txtDescuento.Text))
                {
                    txtDescuento.Text = UseObject.RemoveSeparatorMil(txtDescuento.Text).ToString();
                    if (Validacion.ConFormato(Validacion.TipoValidacion.Numeros,
                        txtDescuento, MiError, "El valor del Descuento que ingreso tiene formato incorrecto."))
                    {
                        if (Convert.ToDouble(txtDescuento.Text) <
                            UseObject.RemoveSeparatorMil(txtSubTotal.Text))
                        {
                            txtTotal.Text = UseObject.InsertSeparatorMil(
                                ((UseObject.RemoveSeparatorMil(txtSubTotal.Text) - Convert.ToDouble(txtDescuento.Text)) +
                                 UseObject.RemoveSeparatorMil(txtIva.Text)).ToString());
                            txtDescuento.Text = UseObject.InsertSeparatorMil(txtDescuento.Text);
                            MiError.SetError(txtDescuento, "");
                            DescuentoMatch = true;
                        }
                        else
                        {
                            MiError.SetError(txtDescuento, "El valor del descuento debe ser menor al valor del Subtotal.");
                            DescuentoMatch = false;
                        }
                    }
                }
                else
                {
                    txtDescuento.Text = "0";
                }
            }*/
        }

        private void txtDescuento_Validating(object sender, CancelEventArgs e)
        {
            txtDescuento_KeyPress(null, new KeyPressEventArgs((char)Keys.Enter));
        }

        /// <summary>
        /// Carga los datos del usuario en el texto del formulario.
        /// </summary>
        private void CargarUsuario()
        {
            miFactura.Usuario = Administracion.Usuario.FrmIniciarSesion.CargarDatosUsuario(this);
        }

        /// <summary>
        /// Crea las respectivas columnas del DataTable miTabla.
        /// </summary>
        private void CrearDataTable()
        {
            miTabla.Columns.Add(new DataColumn("Id", typeof(int)));
            miTabla.Columns.Add(new DataColumn("Codigo", typeof(string)));
            miTabla.Columns.Add(new DataColumn("Articulo", typeof(string)));
            miTabla.Columns.Add(new DataColumn("Cantidad", typeof(int)));
            miTabla.Columns.Add(new DataColumn("ValorUnitario", typeof(int)));
            miTabla.Columns.Add(new DataColumn("Descuento", typeof(string)));
            miTabla.Columns.Add(new DataColumn("ValorMenosDescto", typeof(double)));
            miTabla.Columns.Add(new DataColumn("Iva", typeof(string)));
            miTabla.Columns.Add(new DataColumn("TotalMasIva", typeof(double)));
            miTabla.Columns.Add(new DataColumn("Valor", typeof(double)));
            miTabla.Columns.Add(new DataColumn("Unidad", typeof(string)));
            miTabla.Columns.Add(new DataColumn("IdMedida", typeof(int)));
            miTabla.Columns.Add(new DataColumn("Medida", typeof(string)));
            miTabla.Columns.Add(new DataColumn("IdColor", typeof(int)));
            miTabla.Columns.Add(new DataColumn("Color", typeof(Image)));
            miTabla.Columns.Add(new DataColumn("Lote", typeof(string)));
        }

        /// <summary>
        /// Carga los recursos del ensamblado usados en el formulario.
        /// </summary>
        private void CargarRecursos()
        {
            tsVerColor.Enabled = EnableColor;
            try
            {
                ImgMedidaStream = assembly.GetManifestResourceStream(ImagenMedida);
                ImgColorStream = assembly.GetManifestResourceStream(ImagenColor);
                ImgLoteStream = assembly.GetManifestResourceStream(ImagenLote);
            }
            catch
            {
                OptionPane.MessageError("Ocurrio un error al cargar los recursos.");
            }

            try
            {
                cbFormaPago.DataSource = miBussinesEstado.Lista();
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }

            try
            {
                LoteConsecutivo = Convert.ToInt32(miBussinesFacturaProveedor.ObtenerNumeroLote());
            }
            catch (Exception ex)
            {
                OptionPane.MessageError("Ocurrio un error al cargar el consecutivo del Lote.\n" + ex.Message);
            }
        }

        /// <summary>
        /// Carga los datos del requeridos para almacenar la Factura.
        /// </summary>
        private void CargarFactura()
        {
            miFactura.Proveedor.CodigoInternoProveedor = MiProveedor.CodigoInternoProveedor;
            miFactura.EstadoFactura.Id = Convert.ToInt32(cbFormaPago.SelectedValue);
            miFactura.Caja.Id = 1;      //CHANGE
            miFactura.Usuario.Id = 6;   //CHANGE
            miFactura.Numero = txtNumeroFactura.Text;
            miFactura.FechaLimite = dtpFechaLimite.Value;
            miFactura.FechaIngreso = FechaHoy;
            if (rbtnDesctoFactura.Checked)
            {
                miFactura.Descuento = Convert.ToDouble(txtDescuentoFactura.Text);
            }
            List<ProductoFacturaProveedor> productos = new List<ProductoFacturaProveedor>();
            foreach (DataRow row in miTabla.Rows)
            {
                var producto = new ProductoFacturaProveedor();
                producto.Producto.CodigoInternoProducto = row["Codigo"].ToString();
                producto.Cantidad = Convert.ToInt32(row["Cantidad"]);
                producto.Producto.ValorVentaProducto = Convert.ToInt32(row["ValorUnitario"]);
                producto.Producto.ValorIva = UseObject.RemoveCharacter(row["Iva"].ToString(), '%');
                producto.Producto.Descuento = UseObject.RemoveCharacter(row["Descuento"].ToString(), '%');
                producto.Lote.CodigoProducto = row["Codigo"].ToString();
                producto.Lote.Numero = row["Lote"].ToString();
                producto.Lote.Fecha = FechaHoy;
                producto.Inventario.CodigoProducto = row["Codigo"].ToString();
                producto.Inventario.IdMedida = Convert.ToInt32(row["IdMedida"]);
                producto.Inventario.IdColor = Convert.ToInt32(row["IdColor"]);
                producto.Inventario.Cantidad = Convert.ToInt32(row["Cantidad"]);
                productos.Add(producto);
            }
            miFactura.Productos = productos;
        }

        /// <summary>
        /// Despliega el proceso del hilo (Thread) para el guardado de la Factura.
        /// </summary>
        private void IniciarGuardado()
        {
            GuardarFactura();
        }

        /// <summary>
        /// Realiza los procedimientos necesarios para el guardado de la Factura.
        /// </summary>
        private void GuardarFactura()
        {
            try
            {
                miFactura.Id = miBussinesFacturaProveedor.IngresarFactura(miFactura);
                miBussinesFacturaProveedor.ActualizarLote(LoteConsecutivo - 1);
                SuccessGuardado = true;
                if (this.InvokeRequired)
                    this.Invoke(new Action(FinishProcessGuardado));
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
                SuccessGuardado = false;
                if (this.InvokeRequired)
                    this.Invoke(new Action(FinishProcessGuardado));
            }
        }

        /// <summary>
        /// Finaliza las funciones del proceso de guardado de la Factura.
        /// </summary>
        private void FinishProcessGuardado()
        {
            miOption.FrmProgressBar.barraProgreso.Style = ProgressBarStyle.Blocks;
            miOption.FrmProgressBar.Closed_ = false;
            miOption.FrmProgressBar.Close();
            this.Enabled = true;
            if (SuccessGuardado)
            {
                OptionPane.MessageSuccess("Las operaciones se realizaron correctamente.");
                if ((int)cbFormaPago.SelectedValue == 1)
                {
                    DialogResult rta = MessageBox.Show("¿Desea ingresar el pago a la Factura de Proveedor?", "Factura Proveedor",
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (rta.Equals(DialogResult.Yes))
                    {
                        var pagoFactura = new Pago.FrmCancelarCompra();
                        pagoFactura.IdFactura = miFactura.Id.ToString();
                        pagoFactura.NumeroFactura = txtNumeroFactura.Text;
                        pagoFactura.txtTotal.Text = txtTotal.Text;
                        pagoFactura.MdiParent = this.MdiParent;
                        pagoFactura.Show();
                    }
                }
                LimpiarFormulario();
            }
        }

        /// <summary>
        /// Valida el texto ingresado como codigo del Proveedor.
        /// </summary>
        /// <returns></returns>
        public bool ValidarCodigoProveedor()
        {
            bool resultado = false;
            if (!Validacion.EsVacio(txtCodigoProveedor, MiError, CodigoProveedorReq))
            {
                if (Validacion.ConFormato(Validacion.TipoValidacion.Numeros,
                    txtCodigoProveedor, MiError, CodigoProveedorFormato))
                {
                    resultado = true;
                }
            }
            return resultado;
        }

        /// <summary>
        /// Despliega el proceso del hilo (Thread) para el cambio del Proveedor.
        /// </summary>
        private void IniciarCambio()
        {
            myDelegate delInstance = new myDelegate(CambiarProveedor);
            this.Invoke(delInstance);
        }

        /// <summary>
        /// Realiza los procedimientos necesarios para el Cambio de proveedor de la Factura.
        /// </summary>
        private void CambiarProveedor()
        {
            try
            {
                IdRegimen.Add(MiProveedor.IdRegimen);
                txtNombreProveedor.Text = MiProveedor.CodigoInternoProveedor + " - NIT: " + MiProveedor.NitProveedor
                                    + " - " + MiProveedor.RazonSocialProveedor;
                MiError.SetError(txtCodigoProveedor, null);
                var penUltimo = IdRegimen[IdRegimen.Count - 2];
                var ultimo = IdRegimen[IdRegimen.Count - 1];
                if (ultimo != penUltimo)
                {
                    if (dgvListaArticulos.RowCount != 0)
                    {
                        var copyMiTabla = miTabla.Copy();
                        while (miTabla.Rows.Count != 0)
                        {
                            miTabla.Rows.Clear();
                        }
                        foreach (DataRow row in copyMiTabla.Rows)
                        {
                            var row_ = miTabla.NewRow();
                            var producto = miBussinesProducto.ProductoBasico(row["Codigo"].ToString());
                            row_["Id"] = Contador++;
                            row_["Codigo"] = row["Codigo"];
                            row_["Articulo"] = row["Articulo"];
                            row_["Cantidad"] = row["Cantidad"];
                            row_["ValorUnitario"] = row["ValorUnitario"];
                            row_["Valor"] = row["Valor"];
                            row_["Unidad"] = row["Unidad"];
                            row_["IdMedida"] = row["IdMedida"];
                            row_["Medida"] = row["Medida"];
                            row_["IdColor"] = row["IdColor"];
                            row_["Color"] = row["Color"];
                            row_["Lote"] = row["Lote"];
                            miTabla.Rows.Add(row_);
                            if (MiProveedor.IdRegimen == 1)
                            {
                                row_["Iva"] = ((Producto)producto[0]).ValorIva;
                                InformacionTributaria(Convert.ToDouble(row_["Iva"]),
                                    (string)row_["Cantidad"], (string)row_["ValorUnitario"]);
                            }
                            else
                            {
                                row_["Iva"] = 0;
                            }
                        }
                        RecargarGridview();
                        if (MiProveedor.IdRegimen == 1)
                        {
                            var totalIva_ = 0;
                            foreach (PanelTributario panelT in miPanelTributario)
                            {
                                totalIva_ = totalIva_ + Convert.ToInt32(panelT.TxtTotalIva.Text);
                            }
                            txtIva.Text = totalIva_.ToString();
                        }
                        else
                        {
                            foreach (PanelTributario panel in miPanelTributario)
                            {
                                panelTributario.Controls.Remove(panel.PanelIva);
                                panelTributario.Controls.Remove(panel.TxtGravado);
                                panelTributario.Controls.Remove(panel.TxtTotalIva);
                            }
                            miPanelTributario.Clear();
                            txtIva.Text = "0";
                        }
                        txtTotal.Text = ((Convert.ToInt32(txtSubTotal.Text) - Convert.ToInt32(txtDescuento.Text)) +
                                     Convert.ToInt32(txtIva.Text)).ToString();
                    }
                }
                SuccessCambio = true;
                FinishProcessCambio();
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
                SuccessCambio = false;
                FinishProcessCambio();
            }
        }

        /// <summary>
        /// Finaliza las funciones del proceso de Cambio de Proveedor.
        /// </summary>
        private void FinishProcessCambio()
        {
            miOption.FrmProgressBar.barraProgreso.Style = ProgressBarStyle.Blocks;
            miOption.FrmProgressBar.Closed_ = false;
            miOption.FrmProgressBar.Close();
            this.Enabled = true;
            if (SuccessCambio)
            {
                OptionPane.MessageSuccess("Las operaciones se realizaron correctamente.");
            }
        }

        /// <summary>
        /// Completa la secuencia de datos de un formulario de extención.
        /// </summary>
        /// <param name="args">Objeto que encapsula la información del formulario.</param>
        void CompletaEventos_Completo(CompletaArgumentosDeEventoEditProveedor args)
        {
            try
            {
                FormProducto = Convert.ToBoolean(args.MiObjeto);
            }
            catch { }
        }

        /// <summary>
        /// Completa la secuencia de datos de un formulario de estención.
        /// </summary>
        /// <param name="args">Objeto que encapsula la información del formulario.</param>
        void CompletaEventos_Completo(CompletaArgumentosDeEvento args)
        {
            try
            {
                if (AddColor)
                {
                    miTallaYcolor = (TallaYcolor)args.MiObjeto;
                    btnAgregar.Focus();
                    if (LoadColorSize)
                    {
                        btnAgregar_Click(this.btnAgregar, null);
                    }
                    AddColor = false;
                }
            }
            catch { }
            try
            {
                if (AddProveedor)
                {
                    var proveedor_ = (DTO.Clases.Proveedor)args.MiObjeto;
                    txtCodigoProveedor.Text = proveedor_.CodigoInternoProveedor.ToString();
                    txtCodigoProveedor_KeyPress(null, new KeyPressEventArgs((char)Keys.Enter));
                    FormProveedor = false;
                    AddProveedor = false;
                }
            }
            catch { }

            try
            {
                FormProveedor = Convert.ToBoolean(args.MiObjeto);
            }
            catch { }

            try
            {
                if (Convert.ToInt32(args.MiObjeto) == 10)
                    PrintEgreso();
            }
            catch { }
        }

        /// <summary>
        /// Valida el texto ingresado como codigo del producto.
        /// </summary>
        /// <returns></returns>
        private bool ValidarCodigo()
        {
            bool resultado = false;
            if (!Validacion.EsVacio(txtCodigoArticulo, MiError, CodigoProductoReq))
            {
                if (Validacion.ConFormato(
                    Validacion.TipoValidacion.LetrasGuionNumeros, txtCodigoArticulo, MiError, CodigoProductoFormato))
                {
                    resultado = true;
                }
            }
            return resultado;
        }

        /// <summary>
        /// Valida el texto ingresado como codigo de barras del producto.
        /// </summary>
        /// <returns></returns>
        private bool ValidarCodigoBarras()
        {
            bool resultado = false;
            if (!Validacion.EsVacio(txtCodigoArticulo, MiError, CodigoProductoReq))
            {
                if (Validacion.ConFormato(
                    Validacion.TipoValidacion.Numeros, txtCodigoArticulo, MiError, CodigoProductoFormato))
                {
                    resultado = true;
                }
            }
            return resultado;
        }

        /// <summary>
        /// Valida si codigo ingresado existe en la base de datos.
        /// </summary>
        /// <param name="codigo">Codigo a verificar.</param>
        /// <returns></returns>
        private bool ExisteProducto(string codigo)
        {
            try
            {
                var barras = miBussinesProducto.ExisteCodigoBarras(codigo);
                var code = miBussinesProducto.ExisteCodigo(codigo);
                if (barras || code)
                    return true;
                else
                    return false;
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// Completa la secuencia de datos de un formulario de estencion.
        /// </summary>
        /// <param name="args">Objeto que encapsula la información del formulario.</param>
        void CompletaEventosm_Completo(CompletaArgumentosDeEventom args)
        {
            try
            {
                var producto = (DTO.Clases.Producto)args.MiMarca;
                txtCodigoArticulo.Text = producto.CodigoInternoProducto;
                txtCodigoArticulo_KeyPress(null, new KeyPressEventArgs((char)Keys.Enter));
            }
            catch { }
        }

        /// <summary>
        /// Carga en memoria los datos del Producto consultado segun su codigo.
        /// </summary>
        /// <param name="codigo">Codigo del Producto a cargar.</param>
        private void CargarProducto(string codigo)
        {
            try
            {
                ArrayProducto = miBussinesProducto.ProductoBasico(codigo);
                MiProducto = (DTO.Clases.Producto)ArrayProducto[0];
                if (!MiProducto.AplicaTalla)
                {
                    miMedida = (ValorUnidadMedida)ArrayProducto[1];
                }
                lblDatosProducto.Text = MiProducto.NombreProducto + "  --  " + MiProducto.NombreMarca;
                if (!MiProducto.AplicaTalla && !MiProducto.AplicaColor)
                {
                    btnTallaYcolor.Enabled = false;
                }
                else
                {
                    btnTallaYcolor.Enabled = true;
                }
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }
        }

        private void IniciarCambioDescuento()
        {
        }

        private void CambiarDescuento()//revisar...
        {
            var table = miTabla.Copy();
            miTabla.Clear();
            Contador = 0;
            txtSubTotal.Text = "0";
            txtDescuento.Text = "0";
            txtIva.Text = "0";
            txtTotal.Text = "0";
            foreach (PanelTributario panel in miPanelTributario)
            {
                panelTributario.Controls.Remove(panel.PanelIva);
                panelTributario.Controls.Remove(panel.TxtGravado);
                panelTributario.Controls.Remove(panel.TxtTotalIva);
            }
            miPanelTributario.Clear();
            foreach (DataRow row in table.Rows)
            {
                MiProducto = new Producto();
                MiProducto.CodigoInternoProducto = row["Codigo"].ToString();
                MiProducto.NombreProducto = row["Articulo"].ToString();
                txtCantidad.Text = row["Cantidad"].ToString();
                txtValorUnitario.Text = row["ValorUnitario"].ToString();
                MiProducto.ValorIva = UseObject.RemoveCharacter(row["Iva"].ToString(), '%');
                if (row["Unidad"].ToString().Equals("Talla"))
                {
                    MiProducto.AplicaTalla = true;
                    miTallaYcolor.IdTalla = Convert.ToInt32(row["IdMedida"]);
                    miTallaYcolor.Talla = row["Medida"].ToString();
                }
                else
                {
                    MiProducto.AplicaTalla = false;
                    miMedida.DescripcionUnidadMedida = row["Unidad"].ToString();
                    miMedida.IdValorUnidadMedida = Convert.ToInt32(row["IdMedida"]);
                    miMedida.DescripcionValorUnidadMedida = row["Medida"].ToString();
                }
                if (Convert.ToInt32(row["IdColor"]).Equals(0))
                {
                    MiProducto.AplicaColor = false;
                }
                else
                {
                    MiProducto.AplicaColor = true;
                    miTallaYcolor.IdColor = Convert.ToInt32(row["IdColor"]);
                    miTallaYcolor.Color = (Image)row["Color"];
                }
                Lote = row["Lote"].ToString();
                /*if (DesctoProducto)
                {
                    txtDescuentoProducto.Text = UseObject.RemoveCharacter(row["Descuento"].ToString(), '%').ToString();
                }*/
                /*else//es pasable....
                {
                    txtDescuentoProducto.Text = txtDescuentoFactura.Text;
                }*/
                EstructurarConsulta();
            }
        }

        private void FinishCambioDescuento()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fecha"></param>
        /// <returns></returns>
        private string CambiarSeparadorFecha(string fecha)
        {
            var miFecha = fecha.Split('/');
            string fechaResult = miFecha[0] + miFecha[1] + miFecha[2];
            return fechaResult;
        }

        /// <summary>
        /// Estructura la informacion en la tabla de memora para ser visualizada.
        /// </summary>
        private void EstructurarConsulta()
        {
            Contador++;
            if (ArrayProducto.Count > 0)
            {
                DataRow row = miTabla.NewRow();
                row["Id"] = Contador;
                row["Codigo"] = MiProducto.CodigoInternoProducto;
                row["Articulo"] = MiProducto.NombreProducto;
                row["Cantidad"] = txtCantidad.Text;
                row["ValorUnitario"] = txtValorUnitario.Text;
                if (rbtnDesctoProducto.Checked)
                {
                    row["Descuento"] = txtDescuentoProducto.Text + "%";
                }
                else
                {
                    row["Descuento"] = txtDescuentoFactura.Text + "%";
                }
                row["ValorMenosDescto"] = Convert.ToDouble(Convert.ToInt32(row["ValorUnitario"]) -
                    (Convert.ToInt32(row["ValorUnitario"]) * UseObject.RemoveCharacter(row["Descuento"].ToString(), '%') / 100));
                if (MiProveedor.IdRegimen == 1)  //Regimen Comun
                {
                    row["Iva"] = MiProducto.ValorIva.ToString() + "%";
                    InformacionTributaria(MiProducto.ValorIva, txtCantidad.Text, row["ValorMenosDescto"].ToString());
                }
                else
                {
                    row["Iva"] = 0 + "%";
                }
                row["TotalMasIva"] = (Convert.ToDouble(row["ValorMenosDescto"]) *
                                      UseObject.RemoveCharacter(row["Iva"].ToString(), '%') / 100) +
                                      Convert.ToDouble(row["ValorMenosDescto"]);
                row["Valor"] = Convert.ToDouble(row["TotalMasIva"]) *
                               Convert.ToDouble(txtCantidad.Text);
                if (MiProducto.AplicaTalla)
                {
                    row["Unidad"] = "Talla";
                    row["IdMedida"] = miTallaYcolor.IdTalla;
                    row["Medida"] = miTallaYcolor.Talla;
                }
                else
                {
                    row["Unidad"] = miMedida.DescripcionUnidadMedida;
                    row["IdMedida"] = miMedida.IdValorUnidadMedida;
                    row["Medida"] = miMedida.DescripcionValorUnidadMedida;
                }
                if (MiProducto.AplicaColor)
                {
                    row["IdColor"] = miTallaYcolor.IdColor;
                    row["Color"] = miTallaYcolor.Color;
                }
                else
                {
                    row["IdColor"] = 0;
                    row["Color"] = null;
                }
                row["Lote"] = Lote;

                txtSubTotal.Text = UseObject.InsertSeparatorMil(
                                   (UseObject.RemoveSeparatorMil(txtSubTotal.Text) +
                                    Convert.ToInt32(txtValorUnitario.Text) * Convert.ToInt32(txtCantidad.Text)
                                   ).ToString());

                ///uso decimal
                /* var c1 = Convert.ToDouble(row["ValorUnitario"]);
                 var c2 = Convert.ToDouble(row["ValorMenosDescto"]);
                 var c = Convert.ToDouble(row["ValorMenosDescto"]);

                 var c3 = Convert.ToDouble(row["Cantidad"]);
                 var l1 = c1 - c2;
                 var l2 = l1 * c3;*/

                /* txtDescuento.Text = UseObject.InsertSeparatorMil(
                     (UseObject.RemoveSeparatorMil(txtDescuento.Text) +
                     (Convert.ToDouble(row["ValorUnitario"]) - Convert.ToDouble(row["ValorMenosDescto"])) *
                      Convert.ToDouble(row["Cantidad"])).ToString());*/

                txtDescuento.Text = UseObject.InsertSeparatorMil
                    ((Convert.ToDecimal(UseObject.RemoveSeparatorMil(txtDescuento.Text)) +
                     (Convert.ToDecimal(row["ValorUnitario"]) - Convert.ToDecimal(row["ValorMenosDescto"])) *
                      Convert.ToDecimal(row["Cantidad"])).ToString()
                    );
                /*if (rbtnDesctoProducto.Checked)
                {*/
                /*txtDescuento.Text = UseObject.InsertSeparatorMil(
                                    (UseObject.RemoveSeparatorMil(txtDescuento.Text) +
                                    ((Convert.ToInt32(row["ValorUnitario"]) - Convert.ToDouble(row["ValorMenosDescto"]))
                                     * Convert.ToInt32(txtCantidad.Text))).ToString());*/

                //}

                var totalIva_ = 0.0;
                foreach (PanelTributario panelT in miPanelTributario)
                {
                    totalIva_ = totalIva_ + Convert.ToDouble(panelT.TxtTotalIva.Text);
                }
                txtIva.Text = UseObject.InsertSeparatorMil(totalIva_.ToString());

                txtTotal.Text = UseObject.InsertSeparatorMil(
                                ((UseObject.RemoveSeparatorMil(txtSubTotal.Text) -
                                  UseObject.RemoveSeparatorMil(txtDescuento.Text)) +
                                  totalIva_).ToString());

                miTabla.Rows.Add(row);
                RecargarGridview();
                ActualizarLote();
                LimpiarCampos();
            }
        }

        /// <summary>
        /// Carga y muestra la informacion tributaria del producto solicitado.
        /// </summary>
        /// <param name="iva">Iva a cargar del producto solicitado.</param>
        /// <param name="cantidad">Cantidad a cargar del Producto solicitado.</param>
        /// <param name="valorUnit">Valor unitario del Producto solicitado.</param>
        private void InformacionTributaria(double iva, string cantidad, string valorUnit)
        {
            try
            {
                var PanelName = "panelIva" + iva.ToString();
                var existe = 0;
                foreach (PanelTributario p in miPanelTributario)
                {
                    if (p.PanelIva.Name.Equals(PanelName))
                    {
                        var ivaGravado = UseObject.RemoveSeparatorMil(p.TxtGravado.Text);
                        p.TxtGravado.Text = UseObject.InsertSeparatorMil(
                                            (ivaGravado + (Convert.ToInt32(cantidad) *
                                            Convert.ToDouble(valorUnit))).ToString());
                        p.TxtTotalIva.Text = UseObject.InsertSeparatorMil(
                            (p.Iva * UseObject.RemoveSeparatorMil(p.TxtGravado.Text) / 100).ToString());
                        existe = 2;
                        break;
                    }
                    else
                    {
                        existe = 1;
                    }
                }
                if (existe == 0)      ///No existe ningun panel.
                {
                    CargarDatosTributarios(iva, cantidad, valorUnit, true, 0);
                }
                else
                {
                    if (existe == 1)  ///No existe el panel buscado.
                    {
                        var panel_ = miPanelTributario[miPanelTributario.Count - 1];
                        CargarDatosTributarios(iva, cantidad, valorUnit, false,
                            panel_.PanelIva.Location.X);

                        if (panel_.PanelIva.Location.X >= 279)
                        {
                            panelTributario.AutoScroll = true;
                            if (panelTributario.AutoScrollMargin.Width < 10 ||
                                panelTributario.AutoScrollMargin.Height < 10)
                            {
                                panelTributario.SetAutoScrollMargin(10, 0);
                            }
                        }
                    }
                }
            }
            catch
            {
            }
        }

        /// <summary>
        /// Carga los datos tributarios en los paneles y textos especificados.
        /// </summary>
        /// <param name="iva">Iva del producto a cargar.</param>
        /// <param name="cantidad"></param>
        /// <param name="valorUnit"></param>
        /// <param name="first">Indica si es el primer panel de la lista.</param>
        /// <param name="location_x">Posicion en pixeles del ultimo panel cargado.</param>
        private void CargarDatosTributarios
            (double iva, string cantidad, string valorUnit, bool first, int location_x)
        {
            var classMiPanelTributario = new PanelTributario();

            var miPanel = CrearPanel(iva, first, location_x);
            panelTributario.Controls.Add(miPanel);

            var lstTexBox = CrearTexbox(iva, first, location_x);

            ///txtGravado
            lstTexBox[0].Text = UseObject.InsertSeparatorMil(
                                (Convert.ToInt32(cantidad) *
                                Convert.ToDouble(valorUnit)).ToString());

            ///txtTotaliva
            lstTexBox[1].Text = UseObject.InsertSeparatorMil(
                ((iva * Convert.ToDouble(lstTexBox[0].Text)) / 100).ToString());

            panelTributario.Controls.Add(lstTexBox[0]);
            panelTributario.Controls.Add(lstTexBox[1]);

            classMiPanelTributario.Iva = iva;
            classMiPanelTributario.PanelIva = miPanel;
            classMiPanelTributario.TxtGravado = lstTexBox[0];
            classMiPanelTributario.TxtTotalIva = lstTexBox[1];
            miPanelTributario.Add(classMiPanelTributario);
        }

        /// <summary>
        /// Crea y carga un panel en el fomulario.
        /// </summary>
        /// <param name="iva">Iva del producto solicitado.</param>
        /// <param name="first">Indica si es el primer panel de la lista.</param>
        /// <param name="location_x">Posicion en pixeles del ultimo panel cargado.</param>
        /// <returns></returns>
        private Panel CrearPanel(double iva, bool first, int location_x)
        {
            var panel = new Panel();
            panel.BackColor = SystemColors.ControlLight;
            panel.BorderStyle = BorderStyle.FixedSingle;
            panel.Size = new Size(100, 25);
            panel.Name = "panelIva" + iva.ToString();
            panel.Controls.Add(CrearLabel(iva));
            if (first)
            {
                panel.Location = new Point(81, 8);
            }
            else
            {
                panel.Location = new Point(location_x + 99, 8);
            }
            return panel;
        }

        /// <summary>
        /// Crea una Etiqueta de texto (Label).
        /// </summary>
        /// <param name="iva">Iva del producto solicitado.</param>
        /// <returns></returns>
        private Label CrearLabel(double iva)
        {
            var lbl = new Label();
            lbl.AutoSize = true;
            lbl.Font = new Font("Microsoft Sans Serif", 9.75F, FontStyle.Bold,
                GraphicsUnit.Point, ((byte)(0)));
            lbl.Location = new Point(34, 4);
            lbl.Name = "lblIva" + iva.ToString();
            lbl.Size = new Size(29, 16);
            lbl.TabIndex = 0;
            lbl.Text = iva.ToString() + "%";
            return lbl;
        }

        /// <summary>
        /// Obtiene una lista de TextBox.
        /// </summary>
        /// <param name="iva">Iva del producto solicitado.</param>
        /// <param name="first">Indica si es el primer panel de la lista.</param>
        /// <param name="location_x">Posicion en pixeles del ultimo panel cargado.</param>
        /// <returns></returns>
        private List<TextBox> CrearTexbox(double iva, bool first, int location_x)
        {
            var txtGravado = NewTexbox();
            txtGravado.Name = "txtIvaGravado" + iva.ToString();
            var txtTotalIva = NewTexbox();
            txtTotalIva.Name = "txtTotalIva" + iva.ToString();
            if (first)
            {
                txtGravado.Location = new Point(81, 32);
                txtTotalIva.Location = new Point(81, 53);
            }
            else
            {
                txtGravado.Location = new Point(location_x + 99, 32);
                txtTotalIva.Location = new Point(location_x + 99, 53);
            }
            var lista = new List<TextBox>();
            lista.Add(txtGravado);
            lista.Add(txtTotalIva);
            return lista;
        }

        /// <summary>
        /// Obtiene un nuevo TextBox.
        /// </summary>
        /// <returns></returns>
        private TextBox NewTexbox()
        {
            var texbox = new TextBox();
            texbox.BackColor = SystemColors.Window;
            texbox.BorderStyle = BorderStyle.FixedSingle;
            texbox.ReadOnly = true;
            texbox.TextAlign = HorizontalAlignment.Right;
            texbox.Size = new System.Drawing.Size(100, 22);
            return texbox;
        }

        /// <summary>
        /// Recarga el DataGridView Productos segun los datos en el DataTable miTable.
        /// </summary>
        private void RecargarGridview()
        {
            IEnumerable<DataRow> query = from datos in miTabla.AsEnumerable()
                                         orderby datos.Field<int>("Id") descending
                                         select datos;
            DataTable copy = query.CopyToDataTable<DataRow>();
            miBindingSource.DataSource = copy;
        }

        /// <summary>
        /// Actualiza el registro del Lote generado y utilizado en un Producto.
        /// </summary>
        private void ActualizarLote()
        {
            if (LoteConsecutivo.ToString() == Lote)
            {
                LoteConsecutivo++;
            }
        }

        /// <summary>
        /// Limpia los campos de Producto del Formulario.
        /// </summary>
        private void LimpiarCampos()
        {
            this.txtCodigoArticulo.Focus();
            this.txtCodigoArticulo.Text = "";
            this.txtCantidad.Text = "";
            this.txtValorUnitario.Text = "";
            this.txtDescuentoProducto.Text = "0";
            lblDatosProducto.Text = "";
            txtLote.Text = "";
            Lote = "";
            MiProducto = null;
            miTallaYcolor.IdColor = 0;
            miTallaYcolor.IdTalla = 0;
            miTallaYcolor.Talla = "";
            miTallaYcolor.Color = null;
        }

        /// <summary>
        /// Limpia todos los campos y controles del formulario.
        /// </summary>
        private void LimpiarFormulario()
        {
            txtCodigoProveedor.Text = "";
            txtNombreProveedor.Text = "";
            txtNumeroFactura.Text = "";
            dtpFechaLimite.Value = FechaHoy;
            while (miTabla.Rows.Count != 0)
            {
                miTabla.Rows.Clear();
            }
            while (dgvListaArticulos.RowCount != 0)
            {
                dgvListaArticulos.Rows.RemoveAt(0);
            }
            foreach (PanelTributario panel in miPanelTributario)
            {
                panelTributario.Controls.Remove(panel.PanelIva);
                panelTributario.Controls.Remove(panel.TxtGravado);
                panelTributario.Controls.Remove(panel.TxtTotalIva);
            }
            miPanelTributario.Clear();
            txtSubTotal.Text = "0";
            txtDescuento.Text = "0";
            txtIva.Text = "0";
            txtTotal.Text = "0";
            MiProveedor = null;
            txtCodigoProveedor.Focus();
            MiError.SetError(txtCodigoArticulo, null);
            MiError.SetError(txtDescuento, null);
        }

        private void PrintEgreso()
        {
            DialogResult rta = MessageBox.Show("¿Desea imprimir el recibo de Egreso?", "Factura Proveedor",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (rta.Equals(DialogResult.Yes))
            {
            }
        }

        /// <summary>
        /// Cierra los Formulario que hayan sido creados como extensión de éste.
        /// </summary>
        private void CerrarForms()
        {
            if (formProveedor != null)
            {
                formProveedor.Close();
            }
            if (FrmProducto != null)
            {
                FrmProducto.Close();
            }
            if (listaProducto != null)
            {
                listaProducto.Close();
            }
        }

    }

    /// <summary>
    /// Representa una clase para la estructura de un panel de informacion tributaria.
    /// </summary>
    internal class PanelTributario
    {
        /// <summary>
        /// Obtiene o establece el Iva a calcular.
        /// </summary>
        public double Iva { set; get; }

        /// <summary>
        /// Obtiene o establece el Pane utilizado para el titulo del Iva cargado.
        /// </summary>
        public Panel PanelIva { set; get; }

        /// <summary>
        /// Obtiene o establece el Texbox utilizado para el grabado del Iva.
        /// </summary>
        public TextBox TxtGravado { set; get; }

        /// <summary>
        /// Obtiene o establece el Texbox utilizado para el total del Iva.
        /// </summary>
        public TextBox TxtTotalIva { set; get; }

        /// <summary>
        /// Inicializa una nueva instancia de la clase PanelTributario.
        /// </summary>
        public PanelTributario()
        {
            this.PanelIva = null;
            this.TxtGravado = null;
            this.TxtTotalIva = null;
        }
    }

    /// <summary>
    /// Representa una clase para la estructura de listado de Formas de Pago.
    /// </summary>
    internal class FormaPago
    {
        /// <summary>
        /// Obtiene o establece la lista de Formas de Pago.
        /// </summary>
        public List<Inventario.Producto.Criterio> lista { set; get; }

        /// <summary>
        /// Inicializa una nueva instancia de la clase FormaPago.
        /// </summary>
        public FormaPago()
        {
            lista = new List<Inventario.Producto.Criterio>();
            lista.Add(new Inventario.Producto.Criterio
            {
                Id = 1,
                Nombre = "Contado"
            });
            lista.Add(new Inventario.Producto.Criterio
            {
                Id = 2,
                Nombre = "Crédito"
            });
        }
    }
}